﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Babelfish.MetaData;
using Babelfish.Node;

namespace Babelfish.XML
{
    /// <summary>
    /// 
    /// </summary>
    public class XmlNode : GeneralNode, INode
    {
        /// <summary>
        /// Gets or sets the node.
        /// </summary>
        /// <value>The node.</value>
        protected System.Xml.XmlNode Node { get; set; }
        /// <summary>
        /// Gets or sets the document.
        /// </summary>
        /// <value>The document.</value>
        protected System.Xml.XmlDocument Document { get; set; }

        /// <summary>
        /// Gets the attributes of this node.
        /// </summary>
        /// <value>The attributes.</value>
        public AttributeCollection Attributes
        {
            get
            {
                AttributeCollection collection = new AttributeCollection();

                if (Node.Attributes == null)
                    return collection;

                foreach (System.Xml.XmlAttribute attribute in Node.Attributes)
                    collection.Add(new GeneralAttribute { Name = attribute.Name, Value = attribute.Value });

                return collection;
            }
        }

        /// <summary>
        /// Gets the name of this node.
        /// </summary>
        /// <value>The name.</value>
        public string Name
        {
            get 
            {
                return Node.Name;
            }
        }

        /// <summary>
        /// Removes this this node from its parent node.
        /// </summary>
        /// <param name="childNode"></param>
        public void Remove(INode childNode)
        {
            
        }

        /// <summary>
        /// Gets the value of this node.
        /// </summary>
        /// <value>The value.</value>
        public string Text
        {
            get 
            {
                var text = string.Empty;

                foreach (System.Xml.XmlNode child in Node.ChildNodes)
                    if (child.NodeType == System.Xml.XmlNodeType.Text || child.NodeType == System.Xml.XmlNodeType.CDATA)
                        text += child.InnerText;

                return text;
            }
        }

        /// <summary>
        /// Gets the metadata of this node, like html or xml comments
        /// </summary>
        /// <value></value>
        public MetaDataCollection MetaData
        {
            get
            {
                var collection = new MetaDataCollection();

                foreach (System.Xml.XmlNode child in Node.ChildNodes)
                    if (child.NodeType == System.Xml.XmlNodeType.Comment)
                        collection.Add(new GeneralMetaData{Name = child.Name, Value = child.Value});

                return collection;
            }
        }

        /// <summary>
        /// Gets a value indicating whether this node has a value.
        /// </summary>
        /// <value><c>true</c> if this node has a value; otherwise, <c>false</c>.</value>
        public bool HasValue
        {
            get 
            {
                return !string.IsNullOrEmpty(Node.InnerText);
            }
        }

        /// <summary>
        /// Gets the parent node of this node.
        /// </summary>
        /// <value>The parent node.</value>
        public INode Parent { get; set; }

        /// <summary>
        /// Gets the siblings of this node.
        /// </summary>
        /// <value>The sibling nodes.</value>
        public NodeCollection Siblings
        {
            get
            {
                throw new NotImplementedException();
            }
        }

        /// <summary>
        /// Gets the child nodes of this node.
        /// </summary>
        /// <value>The child nodes.</value>
        public NodeCollection ChildNodes
        {
            get 
            {
                NodeCollection collection = new NodeCollection();

                foreach (System.Xml.XmlNode child in Node.ChildNodes)
                    collection.Add(new XmlNode { Node = child, Parent = this });

                return collection;
            }
        }
    }
}
